/* UniApo: DDLStatement
 * filename:  DDLStatement.h
 * date:      July 2010
 * author:    Jeffrey Geyssens
 * about:     This file contains the library header for the DDLStatement
 *            SQLStatement subclass:. It contains the specific
 *            implementations for formatting and testing a DDLStatement.

 * Marked as completed: 3rd june 2010 and no changes since
 */

#ifndef _DDLSTATEMENT_H
#define	_DDLSTATEMENT_H
#include "SQLStatement.h"

class DDLStatement : public SQLStatement {
public:
    DDLStatement();
    DDLStatement(const DDLStatement& orig);
    virtual ~DDLStatement();
    void delTable();

protected:
    string table;
    bool format(); //Removes unneeded whitespaces from statement
    void revert(); //Drops effected table from db
    //bool test(); //Tests



};

DDLStatement::DDLStatement() {
}

DDLStatement::DDLStatement(const DDLStatement& orig) {
    statement = orig.statement;
    type = orig.type;
}

DDLStatement::~DDLStatement() {
}

bool DDLStatement::format() {

    //Remove trailing whitespaces in front of string
    type = DDL;
    string temp;
    int i, j, begin, end;
   
    //insure that "CREATE TABLE " is at the beginning of the string
    begin = (statement.find("CREATE TABLE "));
    if (begin == statement.npos) {
        cerr << "ERROR (DDLStatement entry): ";
        cerr << "No CREATE TABLE present in DDL Statement" << endl;
        return false;
    }
    //Strip characters before "CREATE TABLE"
    //statement = statement.substr(i, statement.size());

    //Make sure that ; is the last character of the statement
    //only one semicolon for a valid DDL statement
    end = (statement.find(");"));

    if (end == statement.npos) {
        cerr << "ERROR (DDLStatement entry): ";
        cerr << "No ) semicolon present to delimite DDL statement" << endl;
        return false;
    }

    statement = statement.substr(begin, end - begin + 2);



    //skip "CREATE TABLE " which is 13 characters
    //note whitespace at last position of the string
    i = 13;
    //Erase all whitespaces newlines and such
    while ((statement[i] == ' ') || (statement[i] == '\n')
            || (statement[i] == '\t'))
        statement.erase(i, 1);


    //temp = statement.substr(i, statement.size());
    begin = statement.substr(i, statement.size()).find("(");
    if (begin == statement.npos) {
        cerr << "Error(DBSFile - Bulk): incorrect syntax:" << endl;
        cerr << statement << "char: " << statement[i] << endl;
        cerr << "expected '('" << endl;
        return false;
    }
    //between i and j is exactly the tablename

    table = statement.substr(i, begin);
    begin = begin + i;

    int l;
    l = table.find(" ");
    //Tablename might have trailing whitespaces
    while (l != table.npos) {
        //statement.erase(i+l,1);
        table.erase(l, 1);
        //statement.erase(i+l,1);
        l = table.find(" ");
    }
    string first;
    first = "CREATE TABLE ";

    stringstream ss;
    ss << first << table << " (";


    end = statement.size() - 2;

    temp = statement.substr(begin, end - begin + 1);

    i = 0;
    while ((temp[1] == ' ') || (temp[1] == '\n')
            || (temp[1] == '\t'))
        temp.erase(1, 1);

    while ((temp[temp.size() - 2] == ' ') || (temp[temp.size() - 2] == '\n')
            || (temp[temp.size() - 2] == '\t'))
        temp.erase(temp.size() - 2, 1);



    j = temp.substr(i,
            temp.size()).find(",");

     while (j != temp.npos) {

          while ((temp[j + i - 1] == ' ') ||
                  (temp[j + i - 1] == '\n') ||
                  (temp[j + i - 1] == '\t'))
              temp.erase(j + i - 1, 1);
          while ((temp[j + i + 1] == ' ') ||
                  (temp[j + i + 1] == '\n') ||
                  (temp[j + i + 1] == '\t'))
              temp.erase(j + i + 1, 1);
          i = i + j + 1;

          j = temp.substr(i,
                  temp.size()).find(",");

     }



    ss << temp.substr(1,temp.size()) << ";";
    statement = ss.str();



    return true; //DDL statements format success
}


void DDLStatement::revert() {
    //Removes test data from test_db
    stringstream drop;
    drop << "DROP TABLE IF EXISTS " << table << ";";

    string temp;
    temp = statement;
    statement = drop.str();

    this->connect(1);

    statement = temp;

}

void DDLStatement::delTable(){
    this->revert();
}
#endif	/* _DDLSTATEMENT_H */

